using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;

namespace ExceptionViews.Client
{
	public sealed class MainForm : Form
	{
		private Button createExceptionsButton;
		private ExceptionControl exceptionControl;

		public MainForm()
			: base()
		{
			this.InitializeComponent();
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.createExceptionsButton = new System.Windows.Forms.Button();
			this.exceptionControl = new ExceptionViews.ExceptionControl();
			this.SuspendLayout();
			// 
			// createExceptionsButton
			// 
			this.createExceptionsButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
						| System.Windows.Forms.AnchorStyles.Right)));
			this.createExceptionsButton.Location = new System.Drawing.Point(8, 8);
			this.createExceptionsButton.Name = "createExceptionsButton";
			this.createExceptionsButton.Size = new System.Drawing.Size(654, 24);
			this.createExceptionsButton.TabIndex = 0;
			this.createExceptionsButton.Text = "Create Exceptions";
			this.createExceptionsButton.Click += new System.EventHandler(this.OnCreateExceptionsButtonClick);
			// 
			// exceptionControl
			// 
			this.exceptionControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
						| System.Windows.Forms.AnchorStyles.Left)
						| System.Windows.Forms.AnchorStyles.Right)));
			this.exceptionControl.Exceptions = null;
			this.exceptionControl.Location = new System.Drawing.Point(8, 39);
			this.exceptionControl.Name = "exceptionControl";
			this.exceptionControl.Size = new System.Drawing.Size(654, 399);
			this.exceptionControl.TabIndex = 6;
			// 
			// MainForm
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 14);
			this.ClientSize = new System.Drawing.Size(670, 443);
			this.Controls.Add(this.exceptionControl);
			this.Controls.Add(this.createExceptionsButton);
			this.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
			this.Name = "MainForm";
			this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
			this.Text = "Exception Handling Test";
			this.ResumeLayout(false);

		}
		#endregion

		[STAThread]
		static void Main()
		{
			Application.Run(new MainForm());
		}

		private void DisplayExceptions(List<Exception> exceptions)
		{
			this.exceptionControl.Exceptions = exceptions;
		}

		private void OnCreateExceptionsButtonClick(object sender, EventArgs e)
		{
			List<Exception> exceptions = new List<Exception>();

			try
			{
				throw new NotSupportedException("A mild exception has occurred.");
			}
			catch(NotSupportedException ex)
			{
				exceptions.Add(ex);
			}

			try
			{
				this.MethodOne();
			}
			catch(ACustomException ex)
			{
				exceptions.Add(ex);
			}

			try
			{
				this.InnerExOne();
			}
			catch(ACustomException ex)
			{
				exceptions.Add(ex);
			}

			try
			{
				MainForm.CreateCustomException();
			}
			catch(ACustomException ex)
			{
				exceptions.Add(ex);
			}

			try
			{
				MainForm.CallMethodWithNull(null);
			}
			catch(ArgumentNullException ex)
			{
				exceptions.Add(ex);
			}

			this.DisplayExceptions(exceptions);
		}

		private void MethodOne()
		{
			this.MethodTwo();
		}

		private void MethodTwo()
		{
			this.MethodThree();
		}

		private void MethodThree()
		{
			throw new ACustomException("A stackable error has occurred.");
		}

		private void InnerExOne()
		{
			this.InnerExTwo();
		}

		private void InnerExTwo()
		{
			try
			{
				MainForm.InnerExThree();
			}
			catch(InvalidOperationException e)
			{
				throw new ACustomException("An invalid operation occurred.", e);
			}
		}

		private static void InnerExThree()
		{
			try
			{
				int z = 0;
				int x = 3 / z;
			}
			catch(DivideByZeroException e)
			{
				throw new InvalidOperationException("Can't divide by zero.", e);
			}
		}

		private static void CreateCustomException()
		{
			throw new ACustomException();
		}

		private static void CallMethodWithNull(string data)
		{
			if(data == null)
			{
				throw new ArgumentNullException("data");
			}
		}
	}
}
